package Search;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.Test;
import utils.ElasticSearchClient;
import java.util.Map;

/**
 * @author：PZ
 * @Date: 2020/12/11 15 20
 */
public class Search2 {
    ObjectMapper mapper = new ObjectMapper();
    RestHighLevelClient client = ElasticSearchClient.getClient();
    String index = "sms-logs-index";
    String type = "sms-logs-type";
    
    /**
     * 根据id查询
     *
     * @throws Exception
     */
    @Test
    public void findById() throws Exception {
        GetRequest request = new GetRequest(index, type, "1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        Map<String, Object> sourceAsMap = response.getSourceAsMap();
        System.out.println(sourceAsMap);
    }
    
    /**
     * ids查询
     *
     * @throws Exception
     */
    @Test
    public void findByIds() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.idsQuery().addIds("1", "10"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * 前缀查询
     *
     * @throws Exception
     */
    @Test
    public void prefixSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.prefixQuery("corpName", "阿里"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * fuzzy查询
     *
     * @throws Exception
     */
    @Test
    public void fuzzySearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.fuzzyQuery("corpName", "格力骑车").prefixLength(0));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * wildcard查询
     *
     * @throws Exception
     */
    @Test
    public void wildcardSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.wildcardQuery("corpName", "格力??"));
        //builder.query(QueryBuilders.wildcardQuery("corpName","格力*"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * 范围查询
     *
     * @throws Exception
     */
    @Test
    public void rangeSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //查询范围:[gte,lte]
        builder.query(QueryBuilders.rangeQuery("fee").gte("10").lte("20"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * regexp查询
     *
     * @throws Exception
     */
    @Test
    public void regexpSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.regexpQuery("mobile", "138[0-9]{7}"));
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * deleteByQuery
     *
     * @throws Exception
     */
    @Test
    public void deleteByQuery() throws Exception {
        DeleteByQueryRequest request = new DeleteByQueryRequest(index);
        request.types(type);
        request.setQuery(QueryBuilders.rangeQuery("fee").lt(20));
        BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
    
    /**
     * filter查询
     *
     * @throws Exception
     */
    @Test
    public void filterSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //使用bool符合查询的filter查询
        boolQueryBuilder.filter(QueryBuilders.termQuery("corpName", "格力汽车"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("fee").gt(20));
        builder.query(boolQueryBuilder);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
        }
    }
    
    /**
     * 高亮查询
     *
     * @throws Exception
     */
    @Test
    public void highLightSearch() throws Exception {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //构建查询
        builder.query(QueryBuilders.matchQuery("smsContent", "团队"));
        // Highlight与query同级所以单独建立
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //指定高亮
        highlightBuilder.field("smsContent", 10).preTags("<font color='red'>").postTags("</font>");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        System.out.println(hits.length);
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //System.out.println(sourceAsMap);
            HighlightField smsContent = hit.getHighlightFields().get("smsContent");
            System.out.println(smsContent);
        }
    }
}
